package chapter02.part04;

import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;

/**
 * 使用目录流 对遍历过程进行更细的操作
 * 
 * @author insight
 * @since 2021/8/21
 */
public class DirStream {
    public static void main(String[] args) throws IOException {
        Path dir = Paths.get("chapter02-io");

        // 不是 Stream 的子接口 是专门用于遍历目录的接口
        try (DirectoryStream<Path> paths = Files.newDirectoryStream(dir)) {
            for (Path path : paths) {
                // do sth
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        
        // 可以使用 glob (简化的正则)
        try (DirectoryStream<Path> paths = Files.newDirectoryStream(dir, "*.java"
        )) {

        } catch (IOException e) {
            e.printStackTrace();
        }
        
        // 访问所有子成员 并传递一个 FileVisitor
        // 访问文件/目录时: visitFile()
        // 目录处理前: preVisitDirectory()
        // 目录处理后: postVisitDirectory()
        // 发生错误时: visitFileFailed()
        // 继续访问: FileVisitResult.CONTINUE
        // 继续访问但跳过子目录: FileVisitResult.SKIP_SUBTREE
        // 继续访问但跳过兄弟目录: FileVisitResult.SKIP_SIBLINGS
        // 终止: FileVisitResult.TERMINATE
        
        // 打印所有子目录
        Files.walkFileTree(dir, new SimpleFileVisitor<>() {

            /**
             * 路径的属性会传入 preVisitDirectory & visitFile
             */
            @Override
            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
                System.out.println(dir);
                return FileVisitResult.CONTINUE;
            }

            /**
             * 覆盖 postVisitDirectory & visitFileFailed
             * 用于访问失败时
             */
            @Override
            public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
                return FileVisitResult.CONTINUE;
            }

            @Override
            public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
                return FileVisitResult.SKIP_SUBTREE;
            }
        });
        
        // 删除目录树
        Files.walkFileTree(dir, new SimpleFileVisitor<>() {
            @Override
            public FileVisitResult visitFile(Path file,
                                             BasicFileAttributes attrs) throws IOException {
                Files.deleteIfExists(file);
                return FileVisitResult.CONTINUE;
            }

            @Override
            public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
                if (exc != null) throw exc;
                Files.deleteIfExists(dir);
                return FileVisitResult.CONTINUE;
            }
        });
    }
}